<?php

namespace wchat\base;

use Kiri\Client;
use wchat\common\Multiprogramming;
use wchat\common\Result;

/**
 * Class Template
 */
abstract class Template extends Multiprogramming
{


    private array  $keywords         = [];
    private string $templateId       = '';
    private string $formId           = '';
    private string $openId           = '';
    private string $page             = 'pages/index/index';
    private string $emphasis_keyword = '';

    /**
     * @param array $keywords
     */
    public function setKeywords(array $keywords): void
    {
        $this->keywords = $keywords;
    }

    /**
     * @param $templateId
     */
    public function setTemplateId($templateId): void
    {
        $this->templateId = $templateId;
    }

    /**
     * @param $formId
     */
    public function setFormId($formId): void
    {
        $this->formId = $formId;
    }

    /**
     * @param $openId
     */
    public function setOpenId($openId): void
    {
        $this->openId = $openId;
    }

    /**
     * @param $page
     */
    public function setPage($page): void
    {
        $this->page = $page;
    }

    /**
     * @param $emphasis_keyword
     */
    public function setEmphasisKeyword($emphasis_keyword): void
    {
        $this->emphasis_keyword = $emphasis_keyword;
    }

    /**
     * @param $index
     * @param $context
     * @param string $color
     */
    public function replaceKeyword($index, $context, string $color = ''): void
    {
        if (empty($color)) {
            $color = '#000';
        }
        $this->keywords['keyword' . $index] = [
            'value' => $context,
            'color' => $color
        ];
    }


    /**
     * @param $color
     * @param $context
     */
    public function addKeyword($context, $color = null): void
    {
        if (empty($color)) {
            $color = '#000';
        }
        $this->keywords['keyword' . (count($this->keywords) + 1)] = [
            'value' => $context,
            'color' => $color
        ];
    }

    abstract public function getUrl();

    abstract public function getHost();

    /**
     * @return Result
     * @throws
     *
     * 奴隶交易通知
     */
    public function sendTemplate(): Result
    {
        $access_token = $this->payConfig->getAccessToken();
        if (empty($access_token)) {
            throw new \Exception('request access_token con\'t null.');
        }

        $params = [
            "touser"      => $this->openId,
            "template_id" => $this->templateId,
            "page"        => $this->page,
            "form_id"     => $this->formId,
            "data"        => $this->keywords,
        ];

        if (!empty($this->emphasis_keyword)) {
            $params['emphasis_keyword'] = $this->emphasis_keyword;
        }

        $this->reset();

        $client = new Client($this->getHost(), 443, true);
        $client->withHeader(['Content-Type' => 'application/json; charset=utf-8']);

        $proxyHost = $this->payConfig->getProxyHost();
        $proxyPort = $this->payConfig->getProxyPort();
        if (!empty($proxyHost) && $proxyPort > 0) {
            $client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
        }

        $client->post($this->getUrl() . '?access_token=' . $access_token, $params);
        $client->close();

        if (!in_array($client->getStatusCode(), [101, 200, 201])) {
            return new Result(code: 505, message: $client->getBody());
        }
        $body = json_decode($client->getBody(), true);
        if (isset($body['errcode']) && $body['errcode'] != 0) {
            return new Result(code: $body['errcode'], message: $body['errmsg']);
        }
        return new Result(code: 0, data: $body);
    }

    /**
     * @return void
     */
    private function reset(): void
    {
        $this->openId     = '';
        $this->keywords   = [];
        $this->formId     = '';
        $this->templateId = '';
        $this->page       = '';
    }

}
